package net.chrisrichardson.ec2deployer.applications

import groovy.mock.interceptor.MockFor
import net.chrisrichardson.ec2deployer.core.EC2Server
import net.chrisrichardson.ec2deployer.util.FileBasedTemplate
import net.chrisrichardson.ec2deployer.cluster.ClusterSpec
import net.chrisrichardson.ec2deployer.cluster.DatabaseTier
import net.chrisrichardson.ec2deployer.core.EC2
import net.chrisrichardson.ec2deployer.cluster.TerracottaTier
import net.chrisrichardson.ec2deployer.cluster.WebServerTier

class TomcatServerTest extends AbstractApplicationServerTestCase {

    String expectedServerDotXml = "expectedServerDotXml"



    public void testStart() {

        mockFileBasedTemplate = new MockFor(FileBasedTemplate.class)

        mockFileBasedTemplate.demand.process {name, params ->
            assertEquals "/templates/server.xml", name
            assertEquals(['jvmRoute': "tomcat0"], params)
            expectedServerDotXml
        }

        mockMySqlServer.demand.addClientApplication {}

        mockTomcatEC2Server.demand.isRunning {true}
        mockTomcatEC2Server.demand.ssh {cmd -> assertEquals "/sbin/service tomcat5 stop", cmd}
        mockTomcatEC2Server.demand.ssh {cmd, text ->
            assertEquals "cat > /usr/share/tomcat5/conf/server.xml", cmd
            assertEquals expectedServerDotXml, text
        }
        mockTomcatEC2Server.demand.ssh {cmd, text ->
            assertEquals "cat >> /etc/sysconfig/tomcat5", cmd
            assertEquals """export CATALINA_OPTS=' -Dfoo=myPrivateDnsName'
export JAVA_HOME=/usr/java/default
""", text
        }
        mockTomcatEC2Server.demand.ssh {cmd -> assertEquals "/sbin/service tomcat5 start", cmd}
        mockWebApp.demand.updateTomcat {tomcatServer, bucketPrefix -> }

        mockTerracottaTier.demand.prepareClient {EC2Server instance -> }
        mockTerracottaTier.demand.addToCatalinaOpts {optionsBuilder -> }


        mockFileBasedTemplate.use {
            mockTomcatEC2Server.use {
                mockMySqlServer.use {

                    mockDatabaseTier.demand.getDatabaseServer { new MySqlServer() }
                    mockDatabaseTier.demand.grantAccessToClient {}
                    mockDatabaseTier.demand.getDatabaseServerDnsName {"myPrivateDnsName"}
                    mockDatabaseTier.demand.getMySqlSlavesDnsName { []}


                    mockDatabaseTier.use {
                        mockTerracottaTier.use {
                            mockWebApp.use {
                                TomcatServer server = new TomcatServer(makeClusterSpec(), new EC2Server(), new DatabaseTier(), new TerracottaTier(), new WebServerTier())
                                server.startTomcat()
                            }
                        }
                    }
                }
            }
        }
    }


    public void testWaitingUntilRunning() {

        mockMySqlServer.demand.addClientApplication {}

        mockTomcatEC2Server.demand.ssh {cmd -> assertEquals "wget --spider --tries=10 --retry-connrefused --waitretry=10 http://localhost:8080/thecontext", cmd}

        mockWebApp.demand.getActualContext { "thecontext"}

        mockTomcatEC2Server.use {
            mockMySqlServer.use {
                mockDatabaseTier.demand.getDatabaseServer { new MySqlServer() }

                mockDatabaseTier.use {
                    mockTerracottaTier.use {
                        mockWebApp.use {
                            TomcatServer server = new TomcatServer(makeClusterSpec(), new EC2Server(), new DatabaseTier(), new TerracottaTier(), new WebServerTier())
                            server.waitUntilRunning()
                        }
                    }
                }
            }
        }
    }

    public void testStartSar() {

        mockMySqlServer.demand.addClientApplication {}

        mockTomcatEC2Server.demand.startSar {}

        mockTomcatEC2Server.use {
            mockMySqlServer.use {
                mockDatabaseTier.demand.getDatabaseServer { new MySqlServer() }

                mockDatabaseTier.use {
                    mockTerracottaTier.use {
                        mockWebApp.use {
                            TomcatServer server = new TomcatServer(makeClusterSpec(), new EC2Server(), new DatabaseTier(), new TerracottaTier(), new WebServerTier())
                            server.startSar()
                        }
                    }
                }
            }
        }
    }

    public void testStopSar() {
        mockMySqlServer.demand.addClientApplication {}

        mockTomcatEC2Server.demand.stopSar {}

        mockTomcatEC2Server.use {
            mockMySqlServer.use {
                mockDatabaseTier.demand.getDatabaseServer { new MySqlServer() }

                mockDatabaseTier.use {
                    mockTerracottaTier.use {
                        mockWebApp.use {
                            TomcatServer server = new TomcatServer(makeClusterSpec(), new EC2Server(), new DatabaseTier(), new TerracottaTier(), new WebServerTier())
                            server.stopSar()
                        }
                    }
                }
            }
        }
    }

    public void testGetSarMonitor() {

        mockMySqlServer.demand.addClientApplication {}

        mockTomcatEC2Server.demand.getSarMonitor {}

        mockTomcatEC2Server.use {
            mockMySqlServer.use {
                mockDatabaseTier.demand.getDatabaseServer { new MySqlServer() }

                mockDatabaseTier.use {
                    mockTerracottaTier.use {
                        mockWebApp.use {
                            TomcatServer server = new TomcatServer(makeClusterSpec(), new EC2Server(), new DatabaseTier(), new TerracottaTier(), new WebServerTier())
                            server.sarMonitor
                        }
                    }
                }
            }
        }
    }

    public void testGetTomcatLog() {
        mockMySqlServer.demand.addClientApplication {}

        mockTomcatEC2Server.demand.ssh {cmd, shouldbeNull, processMonitor ->
            assertEquals "cat /var/log/tomcat5/catalina.out", cmd
            assertNull shouldbeNull
        }

        mockTomcatEC2Server.use {
            mockMySqlServer.use {
                mockDatabaseTier.demand.getDatabaseServer { new MySqlServer() }

                mockDatabaseTier.use {
                    mockTerracottaTier.use {
                        mockWebApp.use {
                            TomcatServer server = new TomcatServer(makeClusterSpec(), new EC2Server(), new DatabaseTier(), new TerracottaTier(), new WebServerTier())
                            File logFile = server.getTomcatLog()
                            assert logFile.exists()
                            println logFile.text
                        }
                    }
                }
            }
        }
    }
}